package com.fang.study.watch;

import com.fang.study.config.MyConf;
import org.apache.zookeeper.AsyncCallback;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

import java.util.concurrent.CountDownLatch;

/**
 * @author fanglingxiao
 * @version 1.0
 * @description 执行顺序
 * 1.当
 * @date 2022/7/6 4:50 下午
 **/
public class WatchCallback implements Watcher, AsyncCallback.StatCallback, AsyncCallback.DataCallback {
    private final ZooKeeper zk;
    private final String watchPath;
    private final MyConf conf;
    private CountDownLatch cdl = new CountDownLatch(1);

    public WatchCallback(ZooKeeper zk, String watchPath, MyConf conf) {
        this.zk = zk;
        this.watchPath = watchPath;
        this.conf = conf;
    }

    /**
     * Watcher 事件回调
     */
    @Override
    public void process(WatchedEvent watchedEvent) {
        switch (watchedEvent.getType()) {
            case None:
                break;
            case NodeCreated:
                // 当节点被创建 重新触发回调
                zk.getData(watchPath, this, this, "sdf");
                break;
            case NodeDeleted:
                // 当节点被删除 设置value为空，并重新设置计数器
                conf.setConf("");
                cdl = new CountDownLatch(1);
                break;
            case NodeDataChanged:
                // 当该节点发生数据变更回调该状态 重新触发回调
                zk.getData(watchPath, this, this, "sdf");
                break;
            case NodeChildrenChanged:
                break;
            default:
        }
    }

    /**
     * AsyncCallback.StatCallback stat回调
     */
    @Override
    public void processResult(int rc, String path, Object ctx, Stat stat) {
        System.out.println("----statCallback回调----");
        if (stat == null) {
            return;
        }
        zk.getData(watchPath, this, this, "fassd");
    }

    /**
     * AsyncCallback.DataCallback 有data回调
     */
    @Override
    public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
        System.out.println("----执行DataCallback的回调----");
        if (null == data) {
            return;
        }
        System.out.println("----设置回调conf的data，唤醒await----");
        String d = new String(data);
        conf.setConf(d);
        cdl.countDown();
    }

    /**
     * 执行顺序
     * 1.触发AsyncCallback.StatCallback的回调
     * 2.当dataCallback有存在返回会触发dadaCallback的回调
     */
    public void aWait() {
        System.out.println("----执行exists----");
        // 判断该节点是否存在并开启watch
        zk.exists(watchPath, this, this, "abc");
        try {
            // 由于是异步回调，所以等待回调后通过
            System.out.println("----await等待----");
            cdl.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
